/*
* Copyright (c) 2011 Connection Road.  All rights reserved.
* This program and the accompanying material are made available
* under the terms of the Eclipse Public Licnese v1.0 which is
* available at http://www.eclipse.org/legal/epl-v10.html
*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using CrSyncFilesForms.Utils;
using CrSyncFilesUtils;
using CrSyncFilesForms.Properties;
using Microsoft.Synchronization.Files;

namespace CrSyncFilesForms {
    public partial class CrSyncUiPreview : Form
    {

        public CrSyncUiPreview()
        {
            InitializeComponent();
            Init();

            CancelButton = ButtonStop;
            AcceptButton = ButtonRun;
            AffectedFiles = new List<CrSyncedFileInfo>();
            _syncEnabled = true;
            _activeColumnEnabled = true;
        }

        /// <summary>
        /// Initializes preview dialog with a default folder pair to process.
        /// </summary>
        public CrSyncUiPreview(IFileSynchronizer fileSynchronizer)
        {
            InitializeComponent();
            Init();
            _shouldProcessAll = (fileSynchronizer.FolderPairs.Count >= 2) ? true : false;
            _folderPairs = fileSynchronizer.FolderPairs;
            _fileSynchronizer = fileSynchronizer;
            AffectedFiles = new List<CrSyncedFileInfo>();
            _syncEnabled = true;
            _activeColumnEnabled = true;


            if (_shouldProcessAll)
            {
                LabelDestinationPath.Text = LabelSourcePath.Text = Resources.TEXT_MULTIPLE_PAIRS;
                Caption = Resources.TEXT_PREVIEW_FOR_MULTIPLE_PAIRS;
            }
            else
            {
                LabelSourcePath.Text = _folderPairs[0].LeftFolder.Path;
                LabelDestinationPath.Text = _folderPairs[0].RightFolder.Path;
                Caption = string.Format(Resources.TEXT_PREVIEW_FOR, _folderPairs[0].FolderPairName);
            }
        }


        /// <summary>
        /// Use this contructor to just display the preview dilog without doing any sync preview.
        /// </summary>
        /// <param name="fileSynchronizer"></param>
        /// <param name="skippedFilesDueToError"></param>
        public CrSyncUiPreview(IFileSynchronizer fileSynchronizer,List<CrSyncSkippChangeInfo> skippedFilesDueToError) : this(fileSynchronizer)
        {
            _syncEnabled = false;
            _fileSynchronizer = fileSynchronizer;
            _folderPairs = fileSynchronizer.FolderPairs;

            _createdFolder = fileSynchronizer.TotalCreatedFolders;
            _createdFile = fileSynchronizer.TotalCreatedFiles;
            _deletedFolder = fileSynchronizer.TotalDeletedFolders;
            _deletedFile = fileSynchronizer.TotalDeletedFiles;
            _renamed = fileSynchronizer.TotalRenamedFiles;
            _overwritten = fileSynchronizer.TotalOverwrittenFiles;

            _errorColumnEnabled = true;
            _activeColumnEnabled = false;
            _skippedFilesToDueError = skippedFilesDueToError;

            ButtonClose.Enabled = true;
            ButtonStop.Visible = false;
            ButtonRun.Visible = false;

            if(_shouldProcessAll)
            {
                Caption = "Errors for All Folder Pairs";
            }
            else
            {
                Caption = string.Format("Errors for Folder Pair :  {0}", _folderPairs[0].FolderPairName);
            }

            // Hide status
            CRSyncStatusBar.Hide();
            ListViewForAffectedFiles.Height += CRSyncStatusBar.Height;
            PanelMid.Location = new Point(0, PanelMid.Location.Y + CRSyncStatusBar.Height);
        }

        private BackgroundWorker _backgroundWorker;

        private CrSyncFileCountHolder _deletedFolder;
        private CrSyncFileCountHolder _deletedFile;
        private CrSyncFileCountHolder _overwritten;
        private CrSyncFileCountHolder _renamed;
        private CrSyncFileCountHolder _createdFile;
        private CrSyncFileCountHolder _createdFolder;
        private CrSyncFileCountHolder _allOperations;

        private ListViewItem _itemDeletedFolderCount;
        private ListViewItem _itemDeletedFileCount;
        private ListViewItem _itemOverwrittenCount;
        private ListViewItem _itemRenamedCount;
        private ListViewItem _itemNewFileCount;
        private ListViewItem _itemNewFolderCount;
        private ListViewItem _itemAllOperations;


        private FileSyncPairManager _pairManager;
        private IFileSynchronizer _fileSynchronizer;
        private List<CrSyncSkippChangeInfo> _skippedFilesToDueError;
        private List<FileSyncPairInfo> _folderPairs;

        private bool _userAborted;
        private bool _shouldProcessAll;
        private bool _syncEnabled;
        private bool _errorColumnEnabled;
        private bool _activeColumnEnabled;

        /// <summary>
        /// Previewed files that are being displayed on the list.
        /// </summary>
        public List<CrSyncedFileInfo> AffectedFiles { get; set; }

        /// <summary>
        /// Files that are being previewed
        /// </summary>
        public List<CrSyncedFileInfo> PreviewedFiles { get; set; }

        public string Caption { get { return Text; } set { Text = value; } }
       


        private void Init()
        {
            InitializeStatistics();
            _shouldProcessAll = false;
            _pairManager = ApplicationGlobals.PairManager;
            _folderPairs = new List<FileSyncPairInfo>();
        }

        
        private void CallBackLoad(object sender, EventArgs e) {

            // Color scheme
            BackColor = CRSyncColors.PreviewWindowBackGround;
            CRSyncStatusBar.BackColor = CRSyncColors.DialogBackGround;
            PanelMid.BackColor = CRSyncColors.DialogBackGround;

            //Initialize labels
            LabelTotalBytesToCopy.Text = "";
            LabelAvoidedBytesMessage.Text = "";
            LabelTotalFilesUntouched.Text = "";

            // Initialize buttons
            ButtonStop.Enabled = true;

            OperationFilter.SelectedIndex = 0;
            InitializeStatsResult();
            InitializeListViewAffectedFiles();
            CRSyncStatusBar.DefaultProgressBar.Style = ProgressBarStyle.Marquee;

            // Initialize background worker
            _backgroundWorker = new BackgroundWorker {WorkerSupportsCancellation = true, WorkerReportsProgress = true};
            _backgroundWorker.DoWork += CallBackWorker;
            _backgroundWorker.ProgressChanged += CallBackWorkerProgressChanged;
            _backgroundWorker.RunWorkerCompleted += CallBackWorkerCompleted;
            if(_syncEnabled)
            {
                _backgroundWorker.RunWorkerAsync();
            }
            else
            {
                ListViewForAffectedFiles.CheckBoxes = false;
                if(_skippedFilesToDueError != null)
                {
                    foreach (var skippedChanged in _skippedFilesToDueError)
                    {
                        var fileNode = (string.IsNullOrEmpty(skippedChanged.ChangeInfo.CurrentFilePath)) ? new FileNode(skippedChanged.FolderPair.RightFolder.Path).Join(skippedChanged.ChangeInfo.NewFilePath) : new FileNode(skippedChanged.FolderPair.RightFolder.Path).Join(skippedChanged.ChangeInfo.CurrentFilePath);
                        var listViewItem =
                            CreateListViewItemForAffectedFile(skippedChanged.ChangeInfo.ChangeType.ToString(),
                                                              "",
                                                              "",
                                                              "",
                                                              fileNode.GetFileName(),
                                                              fileNode.GetParentPath(),
                                                              "",
                                                              "",
                                                              "["+skippedChanged.ChangeInfo.SkipReason+"] "+skippedChanged.ChangeInfo.Exception.Message);
                        ListViewForAffectedFiles.Items.Add(listViewItem);
                    }
                }
            }
        }

        

         /// <summary>
         /// Resets the statistic values
         /// </summary>
         private void InitializeStatistics()
         {
             _deletedFolder = new CrSyncFileCountHolder();
             _deletedFile = new CrSyncFileCountHolder();
             _overwritten = new CrSyncFileCountHolder();
             _renamed = new CrSyncFileCountHolder();
             _createdFolder = new CrSyncFileCountHolder();
             _createdFile = new CrSyncFileCountHolder();
             _allOperations = new CrSyncFileCountHolder();
         }

        // Initializes the view for the lists of files detected for change
       private void InitializeListViewAffectedFiles() {
            ListViewForAffectedFiles.Clear();
            if (_activeColumnEnabled) { ListViewForAffectedFiles.Columns.Add("Active", 50); }
            ListViewForAffectedFiles.Columns.Add("Operation", 80);
            if(_errorColumnEnabled){ ListViewForAffectedFiles.Columns.Add("Error", 300);}
            ListViewForAffectedFiles.Columns.Add("Source File", 120);
            ListViewForAffectedFiles.Columns.Add("Source Path", 120);
            ListViewForAffectedFiles.Columns.Add("Last Modified", 120);
            ListViewForAffectedFiles.Columns.Add("Target File", 120);
            ListViewForAffectedFiles.Columns.Add("Target Path", 120);
            ListViewForAffectedFiles.Columns.Add("Last Modified", 120);
            ListViewForAffectedFiles.Columns.Add("Bytes to Copy", 100);

            ListViewForAffectedFiles.CheckBoxes = true;
            ListViewForAffectedFiles.ItemChecked += CallBackAffectedFilesItemChecked;

            ListViewForAffectedFiles.HeaderStyle = ColumnHeaderStyle.Nonclickable;
            ListViewForAffectedFiles.View = View.Details;
       }

       // Initializes the statistic tables for all operations
       private void InitializeStatsResult()
       {
           ListViewStats.BeginUpdate();

           ListViewStats.Clear();
           ListViewStats.Columns.Add("Operations", 130);
           ListViewStats.Columns.Add("Count", 60);

           _itemDeletedFolderCount = new ListViewItem("Delete Folder");
           _itemDeletedFolderCount.SubItems.Add(_deletedFolder.Success.ToString());
           if(_deletedFolder.Total > 0)
           {
               _itemDeletedFolderCount.ForeColor = Color.Red;
           }

           _itemDeletedFileCount = new ListViewItem("Delete");
           _itemDeletedFileCount.SubItems.Add(_deletedFile.Success.ToString());
           if(_deletedFile.Total > 0)
           {
               _itemDeletedFileCount.ForeColor = Color.Red;
           }

           _itemOverwrittenCount = new ListViewItem("Overwrite");
           _itemOverwrittenCount.SubItems.Add(_overwritten.Success.ToString());
           if(_overwritten.Total > 0)
           {
               _itemOverwrittenCount.ForeColor = Color.Red;
           }

           _itemRenamedCount = new ListViewItem("Rename");
           _itemRenamedCount.SubItems.Add(_renamed.Success.ToString());

           _itemNewFileCount = new ListViewItem("New");
           _itemNewFileCount.SubItems.Add(_createdFile.Success.ToString());

           _itemNewFolderCount = new ListViewItem("Create Folder");
           _itemNewFolderCount.SubItems.Add(_createdFolder.Success.ToString());

           var itemSpacer = new ListViewItem(" ");
           itemSpacer.SubItems.Add("------");

           _itemAllOperations = new ListViewItem("All Operations");
           _allOperations = new CrSyncFileCountHolder();
           _allOperations.Add(new List<CrSyncFileCountHolder>{_deletedFolder,
                                                    _deletedFile,
                                                    _overwritten,
                                                    _renamed,
                                                    _createdFile,
                                                    _createdFolder});

           _itemAllOperations.SubItems.Add(_allOperations.Success.ToString());

           ListViewStats.Items.Add(_itemDeletedFolderCount);
           ListViewStats.Items.Add(_itemDeletedFileCount);
           ListViewStats.Items.Add(_itemOverwrittenCount);
           ListViewStats.Items.Add(_itemRenamedCount);
           ListViewStats.Items.Add(_itemNewFileCount);
           ListViewStats.Items.Add(_itemNewFolderCount);
           ListViewStats.Items.Add(itemSpacer);
           ListViewStats.Items.Add(_itemAllOperations);

           ListViewStats.HeaderStyle = ColumnHeaderStyle.Nonclickable;
           ListViewStats.View = View.Details;
           ListViewStats.Scrollable = false;
       }


        /// <summary>
        /// Utility static method for creating a list view item for the applied changed file
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="sourceFile"></param>
        /// <param name="sourceDirectory"></param>
        /// <param name="sourceLastModified"></param>
        /// <param name="targetFile"></param>
        /// <param name="targetDirectory"></param>
        /// <param name="targetLastModified"></param>
        /// <param name="bytesToCopy"></param>
        /// <param name="errorMessage"></param>
        /// <returns></returns>
        public ListViewItem CreateListViewItemForAffectedFile(string operation, string sourceFile, string sourceDirectory,string sourceLastModified, string targetFile, string targetDirectory,string targetLastModified,string bytesToCopy, string errorMessage)
        {
            ListViewItem operationItem;
            if(_activeColumnEnabled)
            {
                operationItem = new ListViewItem {Checked = true};
                operationItem.SubItems.Add(operation);
            }
            else
            {
                operationItem = new ListViewItem(operation);
            }
            
            if(!string.IsNullOrEmpty(errorMessage))
            {
                operationItem.SubItems.Add(errorMessage);
                operationItem.ForeColor = Color.Red;
            }
            operationItem.SubItems.Add(sourceFile);
            operationItem.SubItems.Add(sourceDirectory);
            operationItem.SubItems.Add(sourceLastModified); //Last Modified
            operationItem.SubItems.Add(targetFile);
            operationItem.SubItems.Add(targetDirectory);
            operationItem.SubItems.Add(targetLastModified); //Last Modified
            operationItem.SubItems.Add(bytesToCopy); //Bytes

            if (operation.Contains("Delete") || operation.Contains("Overwrite"))
            {
                operationItem.ForeColor = Color.Red;
            }

            return operationItem;
        }

        public ListViewItem CreateListViewItemForAffectedFile(string operation, string sourceFile, string sourceDirectory, string sourceLastModified, string targetFile, string targetDirectory, string targetLastModified, string bytesToCopy)
        {
            return CreateListViewItemForAffectedFile(operation, sourceFile, sourceDirectory, sourceLastModified,
                                                     targetFile, targetDirectory, targetLastModified, bytesToCopy, null);
        }

        

        private void CallBackClose(object sender, EventArgs e) {
            Close();
        }

        private void CallBackStop(object sender, EventArgs e)
        {
            _userAborted = true;
            _fileSynchronizer.CancelPending = true;
        }

        private void CallBackRun(object sender, EventArgs e) {

            // Unbind preview event handlers
            _fileSynchronizer.PreviewingSync -= CallBackFileSyncPreviewUpdate;
            
            // Set file exclusion if available
            var filesToExclude = GetFilesToExclude();
            _fileSynchronizer.CrSynchedFileInfoToExclude = filesToExclude;
            _fileSynchronizer.PreviewMode = false;
            if (_shouldProcessAll)
            {
                var dialogRun = new CrSyncUiRun(_fileSynchronizer);
                Hide();
                dialogRun.ShowDialog(Program.MainWindow);

                // Update last run
                var datetimeNow = DateTime.Now;
                foreach(var folderPair in _folderPairs)
                {
                    _pairManager.UpdateFolderPair(folderPair,datetimeNow);
                }
               
            } 
            else
            {
                var dialogRun = new CrSyncUiRun(_fileSynchronizer);
                Hide();
                dialogRun.ShowDialog(Program.MainWindow);

                // Update last run
                _pairManager.UpdateFolderPair(_folderPairs[0], DateTime.Now);
            }
        }

        private void CallBackResized(object sender, EventArgs e)
        {
           //TODO
        }

        // The default background worker callback
        private void CallBackWorker(object sender, DoWorkEventArgs e)
        {
            ApplicationGlobals.SetVerboseMessage("Running synchronization in PREVIEW MODE");

            
            //_fileSynchronizer = new FileSynchronizer(_folderPairs, true);
            _fileSynchronizer.PreviewMode = true;
            _fileSynchronizer.PreviewingSync += CallBackFileSyncPreviewUpdate;
            _fileSynchronizer.VerboseMessages += CallBackVerboseMessages;
            _fileSynchronizer.LogMessages += CallBackFileSyncLogEventMessages;
            _fileSynchronizer.FolderPairSyncingError += CallBackFolderPairSyncError;
            _fileSynchronizer.FileSyncingError += CallBackFileSyncError;
            _fileSynchronizer.Synchronize(0, ApplicationGlobals.CfgDefaultPauseTime);
        }


        protected virtual void CallBackFileSyncPreviewUpdate(object sender, FileSyncEventArgs args)
        {
            _backgroundWorker.ReportProgress(0,args);
        }

        protected virtual void CallBackVerboseMessages(object sender, FileSyncMessageEventArgs args)
        {
            ApplicationGlobals.SetVerboseMessage(args.Message);
        }

        protected virtual void CallBackFileSyncLogEventMessages(object sender, FileSyncMessageEventArgs args)
        {
            CrSyncFilesUtility.WriteLog(args.Message, ApplicationGlobals.CrSyncLogFilePath);
        }

        protected virtual void CallBackFileSyncError(object sender, FileSyncErrorEventArgs args)
        {
            CrSyncFilesUtility.WriteLog(args.Exception.ToString(), ApplicationGlobals.CrSyncCriticalLogFilePath);
            MessageBox.Show(args.Message, "CRSyncFiles", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        protected virtual void CallBackFolderPairSyncError(object sender, FileSyncErrorEventArgs args)
        {
            // NOTE : Filter for codeplex
            ApplicationGlobals.SetVerboseMessage("Unable to sync Folder Pair :  "+args.FolderPair.FolderPairName+". "+args.Message);
        }

        
        // Fires when main background worker invokes the progress reporting.
        private void CallBackWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
        {

            var eventInfo = e.UserState as FileSyncEventArgs;
            if (eventInfo != null)
            {
                CRSyncStatusBar.StatusMessage = eventInfo.Message ?? CRSyncStatusBar.StatusMessage;

                // Update statistics
                UpdateStaticsCounter(eventInfo.FileSyncStatistics);

                // Add the current file synced info to the list of affected files
                if(eventInfo.FileSynchedInfo != null)
                {
                    AffectedFiles.Add(eventInfo.FileSynchedInfo);
                }

                // Update the display of affected files
                //UpdateAffectedFilesListView(eventInfo.FileSynchedInfo);
            }
        }


        // This method will be fired when the synchronization ( in prview mode ) is finished.
        private void CallBackWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {

            if (_userAborted)
            {
                Close();
            }

            // Updates progress bar behavior
            CRSyncStatusBar.DefaultProgressBar.Style = ProgressBarStyle.Continuous;
            CRSyncStatusBar.Progress = 100;

            ButtonClose.Enabled = true;
            ButtonStop.Enabled = false;

            // Updates operation stats
            _renamed = _fileSynchronizer.PreviewedRenamedFiles;
            _createdFolder = _fileSynchronizer.PreviewedCreatedFolders;
            _createdFile = _fileSynchronizer.PreviewedCreatedFiles;
            _overwritten = _fileSynchronizer.PreviewedOverWrittenFiles;
            _deletedFolder = _fileSynchronizer.PreviewedDeletedFolders;
            _deletedFile = _fileSynchronizer.PreviewedDeletedFiles;
            InitializeStatsResult();
            

            // Updates various labels/messages
            LabelTotalFilesUntouched.Text = string.Format(Resources.TEXT_FOUND_FILES_THAT_DID_NOT_REQUIRE_ACTION, _fileSynchronizer.TotalFilesUntouched);
            LabelTotalBytesToCopy.Text = string.Format(Resources.TEXT_TOTAL_BYTES_TO_COPY, _fileSynchronizer.TotalBytesToCopy);

            LabelAvoidedBytesMessage.Text = string.Format(Resources.TEXT_AVOIDED_COPYING_BYTES,_fileSynchronizer.AvoidedBytes,_fileSynchronizer.TotalFilesUntouched); 
            
            
            CRSyncStatusBar.StatusMessage = "Done";
            
            ButtonRun.Enabled = true;

            

            // Bind filter event ( Combobox filter )
            OperationFilter.SelectedIndexChanged += OperationFilterSelection;

            // Temporarily store affected files
            PreviewedFiles = _fileSynchronizer.PreviewedFiles;

            // Repopulate the list view object of all affected files.
            RefreshAffectedFileListView(PreviewedFiles);

            //Update the filter drop dow and make those operations avaialble the are only present on the current affected files
            UpdateAvailableFilters();
            OperationFilter.SelectedIndex = 0;

            // Hide status
            CRSyncStatusBar.Hide();
            ListViewForAffectedFiles.Height += CRSyncStatusBar.Height;
            PanelMid.Location = new Point(0, PanelMid.Location.Y + CRSyncStatusBar.Height);

            CancelButton = ButtonClose;

        }



        // Convenience method for updating the statics counter
        private void UpdateStaticsCounter(CrSyncFileStatistics crSyncFileStatistics)
        {
           if(crSyncFileStatistics != null)
            {

                //ListViewResults.BeginUpdate();

                // Update Deleted Objects
                if(crSyncFileStatistics.TotalDeletedFiles != null)
                {
                    ListViewItem.ListViewSubItem statItem = _itemDeletedFileCount.SubItems[1];
                    statItem.Text = crSyncFileStatistics.TotalDeletedFiles.Success.ToString();
                    if(crSyncFileStatistics.TotalDeletedFiles.Success > 0)
                    {
                        statItem.ForeColor = Color.Red;
                        _itemDeletedFileCount.ForeColor = Color.Red;
                    }
                }

                if(crSyncFileStatistics.TotalDeletedFolders != null)
                {
                    ListViewItem.ListViewSubItem statItem = _itemDeletedFolderCount.SubItems[1];
                    statItem.Text = crSyncFileStatistics.TotalDeletedFolders.Success.ToString();
                    if(crSyncFileStatistics.TotalDeletedFolders.Success > 0 )
                    {
                        statItem.ForeColor = Color.Red;
                        _itemDeletedFolderCount.ForeColor = Color.Red;
                    }
                }

                // Update created Objects.
                if(crSyncFileStatistics.TotalCreatedFiles != null)
                {
                    ListViewItem.ListViewSubItem statItem = _itemNewFileCount.SubItems[1];
                    statItem.Text = crSyncFileStatistics.TotalCreatedFiles.Success.ToString();
                }

                if (crSyncFileStatistics.TotalCreatedFolders != null)
                {
                    ListViewItem.ListViewSubItem statItem = _itemNewFolderCount.SubItems[1];
                    statItem.Text = crSyncFileStatistics.TotalCreatedFolders.Success.ToString();
                }

                // Update other Objects.
                if (crSyncFileStatistics.TotalOverWrittenFiles != null)
                {
                    ListViewItem.ListViewSubItem statItem = _itemOverwrittenCount.SubItems[1];
                    statItem.Text = crSyncFileStatistics.TotalOverWrittenFiles.Success.ToString();
                }

                if (crSyncFileStatistics.TotalRenamedFiles != null)
                {
                    ListViewItem.ListViewSubItem statItem = _itemRenamedCount.SubItems[1];
                    statItem.Text = crSyncFileStatistics.TotalRenamedFiles.Success.ToString();
                }

                // Total counts
               if(crSyncFileStatistics.TotalOperations != null)
               {
                   ListViewItem.ListViewSubItem totalCount = _itemAllOperations.SubItems[1];
                   totalCount.Text = crSyncFileStatistics.TotalOperations.Success.ToString();
               }
                

                //ListViewResults.EndUpdate();
            }
        }

        // Method for updating the list of affected files
        private void UpdateAffectedFilesListView(CrSyncedFileInfo crSynchedFileInfo)
        {
            if(crSynchedFileInfo != null)
            {
                ListViewItem affectedItem = CreateListViewItemForAffectedFile(crSynchedFileInfo.ChangeTypeDisplayString,
                                                                              crSynchedFileInfo.SourceFileName,
                                                                              crSynchedFileInfo.GetSourceOrigin(),
                                                                              crSynchedFileInfo.SourceLastModified,
                                                                              crSynchedFileInfo.DestinationFileName,
                                                                              crSynchedFileInfo.GetDestinationOrigin(),
                                                                              crSynchedFileInfo.DestinationLastModified,
                                                                              string.Format("{0:0,0}", crSynchedFileInfo.TotalBytesCopied));
                ListViewForAffectedFiles.Items.Add(affectedItem);
                ListViewForAffectedFiles.EnsureVisible(ListViewForAffectedFiles.Items.Count - 1);
            }

            
        }

        // Method for filtering affected files
        protected void FilterAffectedFilesWithFilter(string filterName)
        {
            AffectedFiles = new List<CrSyncedFileInfo>();
            ListViewForAffectedFiles.Items.Clear();

            // Filter);
            foreach (var crSynchedFileInfo in PreviewedFiles)
            {
                if ((crSynchedFileInfo.ChangeTypeDisplayString == filterName) || (filterName == "All Operations"))
                {
                    AffectedFiles.Add(crSynchedFileInfo);
                    ListViewItem affectedItem = CreateListViewItemForAffectedFile(crSynchedFileInfo.ChangeTypeDisplayString,
                                                                              crSynchedFileInfo.SourceFileName,
                                                                              crSynchedFileInfo.GetSourceOrigin(),
                                                                              crSynchedFileInfo.SourceLastModified,
                                                                              crSynchedFileInfo.DestinationFileName,
                                                                              crSynchedFileInfo.GetDestinationOrigin(),
                                                                              crSynchedFileInfo.DestinationLastModified,
                                                                              string.Format("{0:0,0}", crSynchedFileInfo.TotalBytesCopied));
                    ListViewForAffectedFiles.Items.Add(affectedItem);
                }
            }
            
        }


        //Method for updating the combox filters
        protected void UpdateAvailableFilters()
        {
            var allFilters = new List<string>{"All Operations", "Delete Folder", "Delete", "Overwrite","Rename","New","Create Folder"};
            var currentFilters = new List<string> {"All Operations"};

            foreach (var crsSyncFileInfo in PreviewedFiles)
            {
                if(!currentFilters.Contains(crsSyncFileInfo.ChangeTypeDisplayString))
                {
                    currentFilters.Add(crsSyncFileInfo.ChangeTypeDisplayString);
                }
            }

            foreach(var filterName in allFilters)
            {
                if(!currentFilters.Contains(filterName))
                {
                    OperationFilter.Items.Remove(filterName);
                }
            }

        }

        // Method fore refreshing the table of affected files
        private void RefreshAffectedFileListView(IEnumerable<CrSyncedFileInfo> changedItems)
        {
            ListViewForAffectedFiles.Items.Clear();
            foreach (var changedItem in changedItems)
            {
                UpdateAffectedFilesListView(changedItem);
            }
            
        }

        protected void OperationFilterSelection(object sender, EventArgs e)
        {
            FilterAffectedFilesWithFilter(OperationFilter.SelectedItem as string);
        }


        // Method for getting files to exclude from sync
        private List<CrSyncedFileInfo> GetFilesToExclude()
        {
            return (from ListViewItem affectedFile in ListViewForAffectedFiles.Items
                    where !affectedFile.Checked
                    select AffectedFiles[affectedFile.Index]).ToList();
        }


        private void CallBackAffectedFilesItemChecked(object sender, ItemCheckedEventArgs args)
        {
            if (AffectedFiles != null)
            {
                var affectedFile = AffectedFiles[args.Item.Index];
                var listViewItem = args.Item;
                if (affectedFile.IsDirectory && (affectedFile.AppliedChangeType == ChangeType.Create))
                {
                    listViewItem.Checked = true;
                }
                else
                {
                    // If user unchecked an item from the list of affected files, then also exclude it from sync
                    if (!listViewItem.Checked)
                    {
                        _fileSynchronizer.CrSynchedFileInfoToExclude.Add(affectedFile);
                    }
                    else
                    {
                        _fileSynchronizer.CrSynchedFileInfoToExclude.Remove(affectedFile);
                    }
                }
            }
        }

        
    }
}
